package com.yusp75.myexam.ui.display

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.yusp75.myexam.com.yusp75.myexam.data.QuestionRepository
import com.yusp75.myexam.com.yusp75.myexam.data.ResultOfAnswer
import com.yusp75.myexam.com.yusp75.myexam.di.PrefManager
import com.yusp75.myexam.data.ExerciseRecord
import com.yusp75.myexam.data.ExerciseRecordDao
import com.yusp75.myexam.data.Question
import com.yusp75.myexam.data.QuestionBounds
import com.yusp75.myexam.di.DataHolder
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import java.util.Timer
import kotlin.concurrent.timer


@OptIn(FlowPreview::class)
class DisplayViewModel(
    private val recordDao: ExerciseRecordDao,
    private val prefManager: PrefManager,
    private val repository: QuestionRepository,

    // koin scope
    private val holder: DataHolder,
) : ViewModel() {

    private val questionType = mapOf(0 to "全部", 1 to "选择", 2 to "判断")
    var questionNumOfPaper: Int = 0  // 试题题目数

    // 完成考试、练习
    private var _isCompleted = MutableLiveData<Boolean>().apply {
        value = false
    }
    val isCompleted = _isCompleted

    // 做题结果
    private var answersOfFailure = mutableListOf<ResultOfAnswer>()

    // 当前题库
    val currentBookId: Int
        get() = holder.bookId

    // --- 保存的做题参数 ---
    // 范围
    private val scope: Int
        get() {
            return prefManager.exerciseScope
        }

    // 类型
    private val _type: String
        get() {
            return questionType[prefManager.questionType] ?: "全部"
        }

    // 顺序
    private val isOrder: Boolean
        get() {
            // 顺序：0， 随机：1
            return prefManager.exerciseOrder == 0
        }

    // 顺序：全部
    private val questionCurrentIdx: Int
        get() {
            return prefManager.questionCurrentIdx
        }

    // 顺序：选择
    private val choiceCurrentIdx: Int
        get() {
            return prefManager.choiceCurrentIdx
        }

    // 顺序：判断
    private val judgeCurrentIdx: Int
        get() {
            return prefManager.judgeCurrentIdx
        }

    // 试卷题数
    private val numOfChoice: Int
        get() {
            return prefManager.numOfChoice
        }
    private val numOfJudge: Int
        get() {
            return prefManager.numOfJudge
        }


    // 取数据
    private val _data = MutableLiveData<String>()
    val data: LiveData<String> get() = _data

    // 分页查询
    private val _currentPage = MutableStateFlow<List<Question>>(emptyList())
    private val currentPage: StateFlow<List<Question>> = _currentPage.asStateFlow()

    private var _currentIndex = MutableStateFlow(0)
    val currentIndex: StateFlow<Int> = _currentIndex

    val currentQuestion: StateFlow<Question?> = currentPage
        .combine(currentIndex) { page, index ->
            page.takeIf { it.isNotEmpty() }?.getOrNull(index.coerceIn(0, page.lastIndex))
                .also { _lastId.value = it?.id ?: 0 }
        }
        .stateIn(
            scope = viewModelScope,
            started = SharingStarted.WhileSubscribed(5000),
            initialValue = null
        )

    // private var lastId: Int
    private val _lastId = MutableLiveData<Int>()
    val lastId: LiveData<Int> get() = _lastId

    private val pageSize = 50

    // 做题时间
    private var myTimer: Timer? = null
    private var startTime: Long = 0
    private var elapsedTime: Long = 0

    private val _timeElapsed = MutableLiveData<Long>()
    val timeElapsed: LiveData<Long> = _timeElapsed

    // 进度条流
    private val _progressFlow = MutableSharedFlow<Int>(
        replay = 1,
        extraBufferCapacity = 10
    )
    private val progressFlow = _progressFlow.asSharedFlow()

    // 函数： 进度条值
    fun emitProgress(progress: Int) {
        viewModelScope.launch {
            _progressFlow.emit(progress)
        }
    }

    // 记录id范围
    private val _questionBounds = MutableStateFlow<QuestionBounds?>(null)
    val questionBounds: StateFlow<QuestionBounds?> = _questionBounds.asStateFlow()

    // ---初始化---
    init {
        _lastId.value = when {
            isOrder -> when (_type) {
                "全部" -> questionCurrentIdx
                "选择" -> choiceCurrentIdx
                "判断" -> judgeCurrentIdx
                else -> 0  // 添加默认情况
            }

            else -> 0
        }
        holder.totalTimeElapsed = 0L
        // emitProgress(_lastId.value ?: 0)

        // 收集进度状态
        viewModelScope.launch {
            progressFlow
                .distinctUntilChanged()
                .debounce(1000)
                .collect { progressValue ->
                    if (_lastId.value != progressValue) {
                        _lastId.value = progressValue
                        loadNextPage(currentBookId, true)
                    }

                }
        }

        viewModelScope.launch {
            try {
                _questionBounds.value = repository.getQuestionBounds(_type)
            } catch (e: Exception) {
                // 处理错误，可以通过另一个StateFlow传递错误信息
                println("获取问题边界失败: ${e.message}")
            }
        }

        // 测试题数量
        questionNumOfPaper = prefManager.numOfChoice + prefManager.numOfJudge
    }

    // --- 函数 ---
    // 加载下一页数据
    suspend fun loadNextPage(bookId: Int, isExercise: Boolean) {
        // 考试
        // 选择30 判断20
        if (!isExercise) {
            when {
                currentPage.value.isEmpty() -> repository.getPaperQuestions(
                    bookId,
                    numOfChoice,
                    numOfJudge
                )
                    .takeIf { it.isNotEmpty() }?.let {
                        _currentPage.value = it
                        holder.questionNum = it.size
                    }

                else -> {
                    holder.resultOfAnswers = answersOfFailure
                    _isCompleted.postValue(true)
                }
            }
        }
        // 练习
        var newPage: List<Question> = mutableListOf()

        // 类型
        // 顺序
        if (isExercise) {
            if (isOrder) {
                newPage = repository.getQuestionsByCursor(
                    bookId = bookId,
                    lastId = lastId.value ?: 0,
                    limit = pageSize,
                    questionType = if (_type == "全部") null else _type
                )

            } else {
                // 随机
                newPage = repository.getRandomTypeQuestions(
                    bookId = bookId,
                    limit = pageSize,
                    random = true,
                    questionType = if (_type == "全部") null else _type
                )
            }
        } // if exercise

        if (newPage.isNotEmpty()) {
            _currentPage.value = newPage
            _currentIndex.value = 0  // 重置当前索引
        }

    }

    // 移动到下一条记录
    fun moveToNext(): Boolean {
        return if (_currentIndex.value < _currentPage.value.size - 1) {
            _currentIndex.value++
            true  // 表示当前页还有数据
        } else {
            false  // 需要加载下一页
        }
    }

    // 获取当前显示的题目
    fun getCurrentQuestion(): Question? {
        return _currentPage.value.getOrNull(_currentIndex.value)
    }

    // 选择答案
    private val _selectedAnswer = MutableLiveData<String>()
    val selectedAnswer: LiveData<String> get() = _selectedAnswer

    // 1、radio 选项，检查答案
    fun checkAnswer(choose: String): Boolean {
        _selectedAnswer.value = choose
        // print("答案: $choose")
        val result = choose == currentQuestion.value?.answer

        // 记录题目：答错，耗时长
        // 复杂if
        /* when {
             !result -> answersOfFailure.add(
                 Result(
                     bookId = currentQuestion.value?.bookId ?: -1,
                     questionId = currentQuestion.value?.id ?: -1,
                     answer = choose
                 )
             )
         }*/

        // 增加练习记录
        viewModelScope.launch(Dispatchers.IO) {
            recordDao.insertRecord(
                ExerciseRecord(
                    bookId = currentBookId,
                    questionId = currentQuestion.value?.id ?: 0,
                    isCorrect = result,
                    isHesitate = false,
                    timeCost = elapsedTime
                )
            )
        }

        // 累计时间
        holder.totalTimeElapsed += elapsedTime

        return result
    }

    // 2. 提交按钮，记录错题
    fun recordFailure() {
        val result = _selectedAnswer.value == currentQuestion.value?.answer
        result.takeIf { !it }?.let {
            answersOfFailure.add(
                ResultOfAnswer(
                    idx = _currentIndex.value,
                    bookId = currentQuestion.value?.bookId ?: -1,
                    questionId = currentQuestion.value?.id ?: -1,
                    answer = _selectedAnswer.value ?: ""
                )
            )
        }
    }

    fun startTimer() {
        myTimer?.cancel()
        startTime = System.currentTimeMillis()
        myTimer = timer(period = 100) {
            elapsedTime = System.currentTimeMillis() - startTime
            _timeElapsed.postValue(elapsedTime)
        }
    }

    fun stopTimer(): Long {
        myTimer?.cancel()
        myTimer = null
        return elapsedTime
    }

    override fun onCleared() {
        super.onCleared()
        myTimer?.cancel()
    }

    // 复位一些标志
    fun reset() {
        _isCompleted.postValue(false)
    }

    // 保存当前 bookId questionId
    fun saveState() {
        _type.takeIf { isOrder }?.let { typeName ->
            when (typeName) {
                "全部" -> prefManager.questionCurrentIdx = currentQuestion.value?.id ?: 0
                "选择" -> prefManager.choiceCurrentIdx = currentQuestion.value?.id ?: 0
                "判断" -> prefManager.judgeCurrentIdx = currentQuestion.value?.id ?: 0
            }
        }
        prefManager.currentBookId = currentBookId
    }

    // 返回问题计数
    fun getQuestionNum(): Int {
        return when (_type) {
            "全部" -> holder.totalQuestionNum
            "选择" -> holder.choiceQuestionNum
            "判断" -> holder.judgeQuestionNum
            else -> 0
        }
    }

    // lastId 在0-100的位置
    fun atPercent(x: Int, a: Int, b: Int): Int {
        require(b > a) { "上限b必须大于下限a" }
        val clampedX = x.coerceIn(a, b)
        return (clampedX - a) * 100 / (b - a)
    }

    fun atPosition(x: Int, a: Int, b: Int): Int {
        require(b > a) { "上限b必须大于下限a" }
        return (b - a) * 100 / x
    }

    //
}